package com.gylang.im.core.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gylang.commons.util.JsonUtils;
import lombok.Data;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author gylang,
 * date 2020/5/5,
 * @version 1.0
 */
@Component
@Data
public class JwtUtils {
    /**
     * jwt ase 秘钥
     */
    @Value("${jwt.jwtSecret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtR0szfDk0RmuxJzyraw3/GEU2TToXwk2bMrzxAzBm+0xRwVgiBQCV7gvePfV02xl8SbYp9EgRObKy8vNdXLkU6kFg4+yzshpRJwSAyIa1UvJwHG6lUpHTa9Tvc9M0f7UATuqF/vLCjX96vQwRtIj9SB47J9f3YLkqcVEyw1aoGrFox65Tr1CNnInSsBpvGpzBoGtWWhKz/Q45M29GUWX+qVp3Td997z+RZZFDXEwNR+YA7vkAcxIOVcLJISzrDyJtbZ/nhlU2CDnuzWZGELvwNzHxmH9DK9U94ZuzB6ubbSvk1zF1Kj9bq72fc50g7IeQFjAiVF47Vg220LtZK0/6wIDAQAB\n}")
    private String jwtSecret;

    /**
     * 用户信息存储的key
     */
    @Value("${jwt.userKey: userKey}")
    private String userKey;

    public String create(Object userInfo, Long expire) {

        //aes对信息加密

        String userInfoStr = JsonUtils.toJson(userInfo);
        String encryptInfo = AesUtils.encrypt(userInfoStr, jwtSecret);
        int expireHour = (int) (expire / (60 * 60 * 1000));

        return JWT.create()
                .withIssuer("gylang")
                .withExpiresAt(DateTime.now().plusHours(expireHour).toDate())
                .withClaim(userKey, encryptInfo)
                .sign(Algorithm.HMAC256(jwtSecret));
    }

    public <T> T getInfo(String token, Class<T> clazz) {

        //解析jwt
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(jwtSecret))
                .withIssuer("gylang")
                .build();
        DecodedJWT decodedjwt = jwtVerifier.verify(token);


        //获得token的头部，载荷和签名，只对比头部和载荷
        String[] headPayload = token.split("\\.");
        //获得jwt解密后头部
        String header = decodedjwt.getHeader();
        //获得jwt解密后载荷
        String payload = decodedjwt.getPayload();
        if (headPayload[0].equals(header) && headPayload[1].equals(payload)) {
            //从jwt中获取token信息和
            Claim userClaim = decodedjwt.getClaim(userKey);
            String userInfo = AesUtils.decrypt(userClaim.asString(), jwtSecret);
            return JsonUtils.toObject(userInfo, clazz);
        }
        return null;
    }
}
